const fs = require("node:fs").promises;
const path = require("node:path");
const DependencyResolver = require("../lib/dependency-resolver");
const yamlUtils = require("../lib/yaml-utils");

class WebBuilder {
    constructor(options = {}) {
        this.rootDir = options.rootDir || process.cwd();
        this.outputDirs = options.outputDirs || [
            path.join(this.rootDir, "dist"),
        ];
        this.resolver = new DependencyResolver(this.rootDir);
        this.templatePath = path.join(
            this.rootDir,
            "tools",
            "md-assets",
            "web-agent-startup-instructions.md"
        );
    }

    parseYaml(content) {
        const yaml = require("js-yaml");
        return yaml.load(content);
    }

    convertToWebPath(filePath, bundleRoot = "sdat-core") {
        // 将绝对路径转换为带点前缀的Web包路径
        // 所有资源都安装在包根目录下，因此使用该路径
        const relativePath = path.relative(this.rootDir, filePath);
        const pathParts = relativePath.split(path.sep);

        let resourcePath;
        if (pathParts[0] === "expansion-packs") {
            // 对于扩展包，移除'expansion-packs/packname'并使用剩余部分
            resourcePath = pathParts.slice(2).join("/");
        } else {
            // 对于sdat-core、common等，移除第一部分
            resourcePath = pathParts.slice(1).join("/");
        }

        return `.${bundleRoot}/${resourcePath}`;
    }

    generateWebInstructions(bundleType, packName = null) {
        // 根据包类型生成动态Web指令
        const rootExample = packName ? `.${packName}` : ".sdat-core";
        const examplePath = packName
            ? `.${packName}/folder/filename.md`
            : ".sdat-core/folder/filename.md";
        const personasExample = packName
            ? `.${packName}/personas/analyst.md`
            : ".sdat-core/personas/analyst.md";
        const tasksExample = packName
            ? `.${packName}/tasks/create-story.md`
            : ".sdat-core/tasks/create-story.md";
        const utilsExample = packName
            ? `.${packName}/utils/template-format.md`
            : ".sdat-core/utils/template-format.md";
        const tasksRef = packName
            ? `.${packName}/tasks/create-story.md`
            : ".sdat-core/tasks/create-story.md";

        return `# Web Agent Bundle 指引

你现在是 SDAT-Method 框架中的一名专业 AI agent。这是一个与 Web 兼容的捆绑版本，包含你角色所需的所有资源。

## 重要指令

1. **遵循所有启动命令**：你的 agent 配置包括定义你行为、个性和方法的启动说明。这些必须严格遵守。

2. **资源导航**：此捆绑包包含你需要的所有资源。资源标有如下标签：

- \`==================== START: ${examplePath} ====================\`
- \`==================== END: ${examplePath} ====================\`

当你需要引用你指令中提到的资源时：

- 查找对应的 START/END 标签
- 格式始终是带点前缀（\`.\`）的完整路径（例如，\`${personasExample}\`, \`${tasksExample}\`)
- 如果指定了章节（例如，\`{root}/tasks/create-story.md#section-name\`），请导航到文件中的该章节

**理解 YAML 引用**：在 agent 配置中，资源在依赖项部分中引用。例如：

\`\`\`yaml
dependencies:
  utils:
    - template-format
  tasks:
    - create-story
\`\`\`

这些引用直接映射到包部分：

- \`utils: template-format\` → 查找 \`==================== START: ${utilsExample} ====================\`
- \`tasks: create-story\` → 查找 \`==================== START: ${tasksRef} ====================\`

3. **执行环境**：你正在 Web 环境中运行。你的所有能力和知识都包含在此捆绑包内。请在这些约束条件下，尽可能高效地提供协助。

4. **主要指令**：你的主要目标已在下方的代理配置中定义。请根据 SDAT-Method 框架，专注于履行你指定的角色。

---

`;
    }

    async cleanOutputDirs() {
        for (const dir of this.outputDirs) {
            try {
                await fs.rm(dir, { recursive: true, force: true });
                console.log(`已清理: ${path.relative(this.rootDir, dir)}`);
            } catch (error) {
                console.debug(`清理目录 ${dir} 失败:`, error.message);
                // 目录可能不存在，没关系
            }
        }
    }

    async buildAgents() {
        const agents = await this.resolver.listAgents();

        for (const agentId of agents) {
            console.log(`  正在构建代理: ${agentId}`);
            const bundle = await this.buildAgentBundle(agentId);

            // Write to all output directories
            for (const outputDir of this.outputDirs) {
                const outputPath = path.join(outputDir, "agents");
                await fs.mkdir(outputPath, { recursive: true });
                const outputFile = path.join(outputPath, `${agentId}.txt`);
                await fs.writeFile(outputFile, bundle, "utf8");
            }
        }

        console.log(
            `已在 ${this.outputDirs.length} 个位置构建了 ${agents.length} 个代理包`
        );
    }

    async buildTeams() {
        const teams = await this.resolver.listTeams();

        for (const teamId of teams) {
            console.log(`  正在构建团队: ${teamId}`);
            const bundle = await this.buildTeamBundle(teamId);

            // Write to all output directories
            for (const outputDir of this.outputDirs) {
                const outputPath = path.join(outputDir, "teams");
                await fs.mkdir(outputPath, { recursive: true });
                const outputFile = path.join(outputPath, `${teamId}.txt`);
                await fs.writeFile(outputFile, bundle, "utf8");
            }
        }

        console.log(
            `已在 ${this.outputDirs.length} 个位置构建了 ${teams.length} 个团队包`
        );
    }

    async buildAgentBundle(agentId) {
        const dependencies =
            await this.resolver.resolveAgentDependencies(agentId);
        const template = this.generateWebInstructions("agent");

        const sections = [template];

        // Add agent configuration
        const agentPath = this.convertToWebPath(
            dependencies.agent.path,
            "sdat-core"
        );
        sections.push(
            this.formatSection(
                agentPath,
                dependencies.agent.content,
                "sdat-core"
            )
        );

        // Add all dependencies
        for (const resource of dependencies.resources) {
            const resourcePath = this.convertToWebPath(
                resource.path,
                "sdat-core"
            );
            sections.push(
                this.formatSection(resourcePath, resource.content, "sdat-core")
            );
        }

        return sections.join("\n");
    }

    async buildTeamBundle(teamId) {
        const dependencies =
            await this.resolver.resolveTeamDependencies(teamId);
        const template = this.generateWebInstructions("team");

        const sections = [template];

        // Add team configuration
        const teamPath = this.convertToWebPath(
            dependencies.team.path,
            "sdat-core"
        );
        sections.push(
            this.formatSection(teamPath, dependencies.team.content, "sdat-core")
        );

        // 添加所有代理
        for (const agent of dependencies.agents) {
            const agentPath = this.convertToWebPath(agent.path, "sdat-core");
            sections.push(
                this.formatSection(agentPath, agent.content, "sdat-core")
            );
        }

        // 添加所有去重后的资源
        for (const resource of dependencies.resources) {
            const resourcePath = this.convertToWebPath(
                resource.path,
                "sdat-core"
            );
            sections.push(
                this.formatSection(resourcePath, resource.content, "sdat-core")
            );
        }

        return sections.join("\n");
    }

    processAgentContent(content) {
        // 首先，用模板替换YAML之前的内容
        const yamlContent = yamlUtils.extractYamlFromAgent(content);
        if (!yamlContent) return content;

        const yamlMatch = content.match(/```ya?ml\n([\s\S]*?)\n```/);
        if (!yamlMatch) return content;

        const yamlStartIndex = content.indexOf(yamlMatch[0]);
        const yamlEndIndex = yamlStartIndex + yamlMatch[0].length;

        // 解析YAML并移除根级和IDE-FILE-RESOLUTION属性
        try {
            const yaml = require("js-yaml");
            const parsed = yaml.load(yamlContent);

            // 移除根级的属性（如果存在）
            delete parsed.root;
            delete parsed["IDE-FILE-RESOLUTION"];
            delete parsed["REQUEST-RESOLUTION"];

            // 也从activation-instructions中移除（如果存在）
            if (
                parsed["activation-instructions"] &&
                Array.isArray(parsed["activation-instructions"])
            ) {
                parsed["activation-instructions"] = parsed[
                    "activation-instructions"
                ].filter((instruction) => {
                    return (
                        typeof instruction === "string" &&
                        !instruction.startsWith("IDE-FILE-RESOLUTION:") &&
                        !instruction.startsWith("REQUEST-RESOLUTION:")
                    );
                });
            }

            // 重新构建YAML
            const cleanedYaml = yaml.dump(parsed, { lineWidth: -1 });

            // 从YAML中获取代理名称用于标题
            const agentName = parsed.agent?.id || "agent";

            // 构建新内容，只包含代理标题和YAML
            const newHeader = `# ${agentName}\n\n重要提示：阅读完整的 YAML 内容，启动激活以改变你的运行状态，遵循启动部分的说明，保持此状态直到收到退出此模式的指令：\n\n`;
            const afterYaml = content.substring(yamlEndIndex);

            return (
                newHeader +
                "```yaml\n" +
                cleanedYaml.trim() +
                "\n```" +
                afterYaml
            );
        } catch (error) {
            console.warn("处理代理YAML失败:", error.message);
            // If parsing fails, return original content
            return content;
        }
    }

    formatSection(path, content, bundleRoot = "sdat-core") {
        const separator = "====================";

        // 如果这是代理文件，则处理代理内容
        if (path.includes("/agents/")) {
            content = this.processAgentContent(content);
        }

        // 用实际的包根目录替换{root}引用
        content = this.replaceRootReferences(content, bundleRoot);

        return [
            `${separator} START: ${path} ${separator}`,
            content.trim(),
            `${separator} END: ${path} ${separator}`,
            "",
        ].join("\n");
    }

    replaceRootReferences(content, bundleRoot) {
        // Replace {root} with the appropriate bundle root path
        return content.replace(/\{root\}/g, `.${bundleRoot}`);
    }

    async validate() {
        console.log("正在验证代理配置...");
        const agents = await this.resolver.listAgents();
        for (const agentId of agents) {
            try {
                await this.resolver.resolveAgentDependencies(agentId);
                console.log(`  ✓ ${agentId}`);
            } catch (error) {
                console.log(`  ✗ ${agentId}: ${error.message}`);
                throw error;
            }
        }

        console.log("\n正在验证团队配置...");
        const teams = await this.resolver.listTeams();
        for (const teamId of teams) {
            try {
                await this.resolver.resolveTeamDependencies(teamId);
                console.log(`  ✓ ${teamId}`);
            } catch (error) {
                console.log(`  ✗ ${teamId}: ${error.message}`);
                throw error;
            }
        }
    }

    async buildAllExpansionPacks(options = {}) {
        const expansionPacks = await this.listExpansionPacks();

        for (const packName of expansionPacks) {
            console.log(`  正在构建扩展包: ${packName}`);
            await this.buildExpansionPack(packName, options);
        }

        console.log(`已构建 ${expansionPacks.length} 个扩展包`);
    }

    async buildExpansionPack(packName, options = {}) {
        const packDir = path.join(this.rootDir, "expansion-packs", packName);
        const outputDirs = [
            path.join(this.rootDir, "dist", "expansion-packs", packName),
        ];

        // Clean output directories if requested
        if (options.clean !== false) {
            for (const outputDir of outputDirs) {
                try {
                    await fs.rm(outputDir, { recursive: true, force: true });
                } catch (error) {
                    // 忽略目录不存在的错误
                }
            }
        }

        // 先构建单独的代理
        const agentsDir = path.join(packDir, "agents");
        try {
            const agentFiles = await fs.readdir(agentsDir);
            const agentMarkdownFiles = agentFiles.filter((f) =>
                f.endsWith(".md")
            );

            if (agentMarkdownFiles.length > 0) {
                console.log(`    正在为 ${packName} 构建单独的代理:`);

                for (const agentFile of agentMarkdownFiles) {
                    const agentName = agentFile.replace(".md", "");
                    console.log(`      - ${agentName}`);

                    // 构建单独的代理包
                    const bundle = await this.buildExpansionAgentBundle(
                        packName,
                        packDir,
                        agentName
                    );

                    // 写入所有输出目录
                    for (const outputDir of outputDirs) {
                        const agentsOutputDir = path.join(outputDir, "agents");
                        await fs.mkdir(agentsOutputDir, { recursive: true });
                        const outputFile = path.join(
                            agentsOutputDir,
                            `${agentName}.txt`
                        );
                        await fs.writeFile(outputFile, bundle, "utf8");
                    }
                }
            }
        } catch (error) {
            console.debug(`    未找到 ${packName} 的代理目录`);
        }

        // 构建团队包
        const agentTeamsDir = path.join(packDir, "agent-teams");
        try {
            const teamFiles = await fs.readdir(agentTeamsDir);
            const teamFile = teamFiles.find((f) => f.endsWith(".yaml"));

            if (teamFile) {
                console.log(`    正在为 ${packName} 构建团队包`);
                const teamConfigPath = path.join(agentTeamsDir, teamFile);

                // Build expansion pack as a team bundle
                const bundle = await this.buildExpansionTeamBundle(
                    packName,
                    packDir,
                    teamConfigPath
                );

                // Write to all output directories
                for (const outputDir of outputDirs) {
                    const teamsOutputDir = path.join(outputDir, "teams");
                    await fs.mkdir(teamsOutputDir, { recursive: true });
                    const outputFile = path.join(
                        teamsOutputDir,
                        teamFile.replace(".yaml", ".txt")
                    );
                    await fs.writeFile(outputFile, bundle, "utf8");
                    console.log(
                        `    ✓ 创建包: ${path.relative(this.rootDir, outputFile)}`
                    );
                }
            } else {
                console.warn(
                    `    ⚠ 在 ${packName}/agent-teams/ 中未找到团队配置`
                );
            }
        } catch (error) {
            console.warn(`    ⚠ 未找到 ${packName} 的agent-teams目录`);
        }
    }

    async buildExpansionAgentBundle(packName, packDir, agentName) {
        const template = this.generateWebInstructions(
            "expansion-agent",
            packName
        );
        const sections = [template];

        // Add agent configuration
        const agentPath = path.join(packDir, "agents", `${agentName}.md`);
        const agentContent = await fs.readFile(agentPath, "utf8");
        const agentWebPath = this.convertToWebPath(agentPath, packName);
        sections.push(this.formatSection(agentWebPath, agentContent, packName));

        // Resolve and add agent dependencies
        const yamlContent = yamlUtils.extractYamlFromAgent(agentContent);
        if (yamlContent) {
            try {
                const yaml = require("js-yaml");
                const agentConfig = yaml.load(yamlContent);

                if (agentConfig.dependencies) {
                    // 处理资源依赖，先尝试扩展包，再尝试核心
                    for (const [resourceType, resources] of Object.entries(
                        agentConfig.dependencies
                    )) {
                        if (Array.isArray(resources)) {
                            for (const resourceName of resources) {
                                let found = false;

                                // Try expansion pack first
                                const resourcePath = path.join(
                                    packDir,
                                    resourceType,
                                    resourceName
                                );
                                try {
                                    const resourceContent = await fs.readFile(
                                        resourcePath,
                                        "utf8"
                                    );
                                    const resourceWebPath =
                                        this.convertToWebPath(
                                            resourcePath,
                                            packName
                                        );
                                    sections.push(
                                        this.formatSection(
                                            resourceWebPath,
                                            resourceContent,
                                            packName
                                        )
                                    );
                                    found = true;
                                } catch (error) {
                                    // Not in expansion pack, continue
                                }

                                // If not found in expansion pack, try core
                                if (!found) {
                                    const corePath = path.join(
                                        this.rootDir,
                                        "sdat-core",
                                        resourceType,
                                        resourceName
                                    );
                                    try {
                                        const coreContent = await fs.readFile(
                                            corePath,
                                            "utf8"
                                        );
                                        const coreWebPath =
                                            this.convertToWebPath(
                                                corePath,
                                                packName
                                            );
                                        sections.push(
                                            this.formatSection(
                                                coreWebPath,
                                                coreContent,
                                                packName
                                            )
                                        );
                                        found = true;
                                    } catch (error) {
                                        // Not in core either, continue
                                    }
                                }

                                // If not found in core, try common folder
                                if (!found) {
                                    const commonPath = path.join(
                                        this.rootDir,
                                        "common",
                                        resourceType,
                                        resourceName
                                    );
                                    try {
                                        const commonContent = await fs.readFile(
                                            commonPath,
                                            "utf8"
                                        );
                                        const commonWebPath =
                                            this.convertToWebPath(
                                                commonPath,
                                                packName
                                            );
                                        sections.push(
                                            this.formatSection(
                                                commonWebPath,
                                                commonContent,
                                                packName
                                            )
                                        );
                                        found = true;
                                    } catch (error) {
                                        // 未在公共文件夹中找到，继续
                                    }
                                }

                                if (!found) {
                                    console.warn(
                                        `    ⚠ 依赖项 ${resourceType}#${resourceName} 在扩展包或核心中未找到`
                                    );
                                }
                            }
                        }
                    }
                }
            } catch (error) {
                console.debug(
                    `解析 ${agentName} 的代理YAML失败:`,
                    error.message
                );
            }
        }

        return sections.join("\n");
    }

    async buildExpansionTeamBundle(packName, packDir, teamConfigPath) {
        const template = this.generateWebInstructions(
            "expansion-team",
            packName
        );

        const sections = [template];

        // Add team configuration and parse to get agent list
        const teamContent = await fs.readFile(teamConfigPath, "utf8");
        const teamFileName = path.basename(teamConfigPath, ".yaml");
        const teamConfig = this.parseYaml(teamContent);
        const teamWebPath = this.convertToWebPath(teamConfigPath, packName);
        sections.push(this.formatSection(teamWebPath, teamContent, packName));

        // Get list of expansion pack agents
        const expansionAgents = new Set();
        const agentsDir = path.join(packDir, "agents");
        try {
            const agentFiles = await fs.readdir(agentsDir);
            for (const agentFile of agentFiles.filter((f) =>
                f.endsWith(".md")
            )) {
                const agentName = agentFile.replace(".md", "");
                expansionAgents.add(agentName);
            }
        } catch (error) {
            console.warn(`    ⚠ 在 ${packName} 中未找到代理目录`);
        }

        // Build a map of all available expansion pack resources for override checking
        const expansionResources = new Map();
        const resourceDirs = [
            "templates",
            "tasks",
            "checklists",
            "workflows",
            "data",
        ];
        for (const resourceDir of resourceDirs) {
            const resourcePath = path.join(packDir, resourceDir);
            try {
                const resourceFiles = await fs.readdir(resourcePath);
                for (const resourceFile of resourceFiles.filter(
                    (f) => f.endsWith(".md") || f.endsWith(".yaml")
                )) {
                    expansionResources.set(
                        `${resourceDir}#${resourceFile}`,
                        true
                    );
                }
            } catch (error) {
                // Directory might not exist, that's fine
            }
        }

        // Process all agents listed in team configuration
        const agentsToProcess = teamConfig.agents || [];

        // Ensure sdat-orchestrator is always included for teams
        if (!agentsToProcess.includes("sdat-orchestrator")) {
            console.warn(
                `    ⚠ 团队 ${teamFileName} 缺少sdat-orchestrator，自动添加`
            );
            agentsToProcess.unshift("sdat-orchestrator");
        }

        // Track all dependencies from all agents (deduplicated)
        const allDependencies = new Map();

        for (const agentId of agentsToProcess) {
            if (expansionAgents.has(agentId)) {
                // Use expansion pack version (override)
                const agentPath = path.join(agentsDir, `${agentId}.md`);
                const agentContent = await fs.readFile(agentPath, "utf8");
                const expansionAgentWebPath = this.convertToWebPath(
                    agentPath,
                    packName
                );
                sections.push(
                    this.formatSection(
                        expansionAgentWebPath,
                        agentContent,
                        packName
                    )
                );

                // Parse and collect dependencies from expansion agent
                const agentYaml = agentContent.match(
                    /```yaml\n([\s\S]*?)\n```/
                );
                if (agentYaml) {
                    try {
                        const agentConfig = this.parseYaml(agentYaml[1]);
                        if (agentConfig.dependencies) {
                            for (const [
                                resourceType,
                                resources,
                            ] of Object.entries(agentConfig.dependencies)) {
                                if (Array.isArray(resources)) {
                                    for (const resourceName of resources) {
                                        const key = `${resourceType}#${resourceName}`;
                                        if (!allDependencies.has(key)) {
                                            allDependencies.set(key, {
                                                type: resourceType,
                                                name: resourceName,
                                            });
                                        }
                                    }
                                }
                            }
                        }
                    } catch (error) {
                        console.debug(
                            `解析 ${agentId} 的代理YAML失败:`,
                            error.message
                        );
                    }
                }
            } else {
                // Use core SDAT version
                try {
                    const coreAgentPath = path.join(
                        this.rootDir,
                        "sdat-core",
                        "agents",
                        `${agentId}.md`
                    );
                    const coreAgentContent = await fs.readFile(
                        coreAgentPath,
                        "utf8"
                    );
                    const coreAgentWebPath = this.convertToWebPath(
                        coreAgentPath,
                        packName
                    );
                    sections.push(
                        this.formatSection(
                            coreAgentWebPath,
                            coreAgentContent,
                            packName
                        )
                    );

                    // Parse and collect dependencies from core agent
                    const yamlContent = yamlUtils.extractYamlFromAgent(
                        coreAgentContent,
                        true
                    );
                    if (yamlContent) {
                        try {
                            const agentConfig = this.parseYaml(yamlContent);
                            if (agentConfig.dependencies) {
                                for (const [
                                    resourceType,
                                    resources,
                                ] of Object.entries(agentConfig.dependencies)) {
                                    if (Array.isArray(resources)) {
                                        for (const resourceName of resources) {
                                            const key = `${resourceType}#${resourceName}`;
                                            if (!allDependencies.has(key)) {
                                                allDependencies.set(key, {
                                                    type: resourceType,
                                                    name: resourceName,
                                                });
                                            }
                                        }
                                    }
                                }
                            }
                        } catch (error) {
                            console.debug(
                                `解析 ${agentId} 的代理YAML失败:`,
                                error.message
                            );
                        }
                    }
                } catch (error) {
                    console.warn(
                        `    ⚠ 代理 ${agentId} 在核心或扩展包中未找到`
                    );
                }
            }
        }

        // 从所有代理中添加所有收集的依赖项
        // 始终优先使用扩展包版本（如果存在）
        for (const [key, dep] of allDependencies) {
            let found = false;

            // Always check expansion pack first, even if the dependency came from a core agent
            if (expansionResources.has(key)) {
                // We know it exists in expansion pack, find and load it
                const expansionPath = path.join(packDir, dep.type, dep.name);
                try {
                    const content = await fs.readFile(expansionPath, "utf8");
                    const expansionWebPath = this.convertToWebPath(
                        expansionPath,
                        packName
                    );
                    sections.push(
                        this.formatSection(expansionWebPath, content, packName)
                    );
                    console.log(`      ✓ 对 ${key} 使用扩展覆盖`);
                    found = true;
                } catch (error) {
                    // Try next extension
                }
            }

            // If not found in expansion pack (or doesn't exist there), try core
            if (!found) {
                const corePath = path.join(
                    this.rootDir,
                    "sdat-core",
                    dep.type,
                    dep.name
                );
                try {
                    const content = await fs.readFile(corePath, "utf8");
                    const coreWebPath = this.convertToWebPath(
                        corePath,
                        packName
                    );
                    sections.push(
                        this.formatSection(coreWebPath, content, packName)
                    );
                    found = true;
                } catch (error) {
                    // 未在核心中找到，继续
                }
            }

            // 如果在核心中也未找到，尝试公共文件夹
            if (!found) {
                const commonPath = path.join(
                    this.rootDir,
                    "common",
                    dep.type,
                    dep.name
                );
                try {
                    const content = await fs.readFile(commonPath, "utf8");
                    const commonWebPath = this.convertToWebPath(
                        commonPath,
                        packName
                    );
                    sections.push(
                        this.formatSection(commonWebPath, content, packName)
                    );
                    found = true;
                } catch (error) {
                    // 未在公共文件夹中找到，继续
                }
            }

            if (!found) {
                console.warn(`    ⚠ 依赖项 ${key} 在扩展包或核心中未找到`);
            }
        }

        // 从扩展包中添加所有剩余资源，这些资源不是作为依赖项包含的
        for (const resourceDir of resourceDirs) {
            const resourcePath = path.join(packDir, resourceDir);
            try {
                const resourceFiles = await fs.readdir(resourcePath);
                for (const resourceFile of resourceFiles.filter(
                    (f) => f.endsWith(".md") || f.endsWith(".yaml")
                )) {
                    const filePath = path.join(resourcePath, resourceFile);
                    const fileContent = await fs.readFile(filePath, "utf8");
                    const fileName = resourceFile.replace(/\.(md|yaml)$/, "");

                    // Only add if not already included as a dependency
                    const resourceKey = `${resourceDir}#${fileName}`;
                    if (!allDependencies.has(resourceKey)) {
                        const fullResourcePath = path.join(
                            resourcePath,
                            resourceFile
                        );
                        const resourceWebPath = this.convertToWebPath(
                            fullResourcePath,
                            packName
                        );
                        sections.push(
                            this.formatSection(
                                resourceWebPath,
                                fileContent,
                                packName
                            )
                        );
                    }
                }
            } catch (error) {
                // 未在扩展包中找到，继续
            }
        }

        return sections.join("\n");
    }

    async listExpansionPacks() {
        const expansionPacksDir = path.join(this.rootDir, "expansion-packs");
        try {
            const entries = await fs.readdir(expansionPacksDir, {
                withFileTypes: true,
            });
            return entries
                .filter((entry) => entry.isDirectory())
                .map((entry) => entry.name);
        } catch (error) {
            console.warn("未找到expansion-packs目录");
            return [];
        }
    }

    listAgents() {
        return this.resolver.listAgents();
    }
}

module.exports = WebBuilder;
